package cn.com.dhcc.turbo.service.exch.cmdata;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.ws.WebServiceContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.exception.FileSplitException;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.compresshandler.CompressResult;
import cn.com.dhcc.app.core.handler.compresshandler.CompressService;
import cn.com.dhcc.app.core.handler.compresshandler.CompressServiceFactory;
import cn.com.dhcc.app.core.handler.compresshandler.CompressStatic.COMPRESS_ALGORITHM;
import cn.com.dhcc.app.core.handler.encrypthandler.EncryptResult;
import cn.com.dhcc.app.core.handler.encrypthandler.EncryptService;
import cn.com.dhcc.app.core.handler.encrypthandler.EncryptServiceFactory;
import cn.com.dhcc.app.core.handler.encrypthandler.EncryptStatic.ENCRYPT_ALGORITHM;
import cn.com.dhcc.app.core.handler.filesplithandler.FileSplitService;
import cn.com.dhcc.app.core.handler.filesplithandler.FileSplitServiceFactory;
import cn.com.dhcc.app.core.handler.filesplithandler.FileSplitStatic;
import cn.com.dhcc.app.core.handler.filesplithandler.FileSplitStatic.FILESPLIT_ALGORITHM;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.util.BeanMapper;
import cn.com.dhcc.app.core.util.CollectionUtil;
import cn.com.dhcc.app.core.util.IpUtil;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.core.util.NetUtil;
import cn.com.dhcc.app.core.util.Status;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.core.util.UUIDGenerator;
import cn.com.dhcc.app.core.util.XstreamUtil;
import cn.com.dhcc.app.pub.core.consts.AppConst;
import cn.com.dhcc.app.pub.core.consts.AppConst.CrossNetType;
import cn.com.dhcc.app.pub.core.consts.AppConst.ExchDataType;
import cn.com.dhcc.app.pub.core.consts.AppConst.PostheadStatus;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.consts.KernelParam;
import cn.com.dhcc.app.pub.core.consts.NodeInfoParam;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.app.pub.core.util.FtpUtil;
import cn.com.dhcc.app.pub.core.util.TurboUtil;
import cn.com.dhcc.app.pub.core.util.ZipUtil;
import cn.com.dhcc.turbo.entity.api.OrderResp;
import cn.com.dhcc.turbo.entity.api.Posthead;
import cn.com.dhcc.turbo.entity.api.ProcessInfo;
import cn.com.dhcc.turbo.entity.api.Processes;
import cn.com.dhcc.turbo.entity.api.RouteEntry;
import cn.com.dhcc.turbo.entity.api.RouteLog;
import cn.com.dhcc.turbo.entity.api.SendResp;
import cn.com.dhcc.turbo.entity.exch.CarvedDiscsUpload;
import cn.com.dhcc.turbo.entity.exch.CarvedDiscsUploadData;
import cn.com.dhcc.turbo.entity.exch.CmData;
import cn.com.dhcc.turbo.entity.exch.CrossNetTmpCmData;
import cn.com.dhcc.turbo.entity.exch.QueueMsgWrapper.ExchageLifecycle;
import cn.com.dhcc.turbo.entity.exch.RecvCmData;
import cn.com.dhcc.turbo.entity.exch.SendCmData;
import cn.com.dhcc.turbo.entity.exch.SendFileData;
import cn.com.dhcc.turbo.entity.registry.AdapterBase;
import cn.com.dhcc.turbo.entity.registry.AdapterInfo;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.service.exch.HttpDataExchRecvService;
import cn.com.dhcc.turbo.service.exch.TurboCompressFilter;
import cn.com.dhcc.turbo.service.exch.TurboEncryptFilter;
import cn.com.dhcc.turbo.service.exch.cmdata.validator.MessageValidator;
import cn.com.dhcc.turbo.service.exch.expired.ExpiredStrategy;
import cn.com.dhcc.turbo.service.exch.filedata.SendFileDataService;
import cn.com.dhcc.turbo.service.registry.BaseInfoService;
import cn.com.dhcc.turbo.service.registry.DataCategoryService;
import cn.com.dhcc.turbo.service.transport.TransportPipeline;

/**
 * 通用数据发送生命周期
 * 
 * 内网到外网生命周期:validate-localstore-waitCarvedDiscs
 * 同网段生命周期:
 *        同节点传输:validate-localstore-sendDataToLocalSys
 *        跨节点传输:validate-localstore-
 * 
 */
@Service(AppIocBean.CM_DATA_EXCHANGE_LIFECYCLE_BEAN)
public class CmDataExchangeLifecycleImpl implements CmDataExchangeLifecycle {
	private static FileSplitService fileSplit = FileSplitServiceFactory.createFileSplitService(FILESPLIT_ALGORITHM.SIMPLE);
	@SuppressWarnings("deprecation")
	private Logger logger = Log.getDetachLogger(LOGTYPE.QUARTZJOB);
	
	private static final String inIp = NodeInfoParam.GAP_PARAM.IP;// FTP服务器地址
	private static final int inPort =NodeInfoParam.GAP_PARAM.Port;// FTP服务器端口
	private static final String inUserName = NodeInfoParam.GAP_PARAM.UserName;// 登录FTP服务器账号
	private static final String inPassword = NodeInfoParam.GAP_PARAM.Password;// 登陆FTP服务器密码
	private static final String inOutput = NodeInfoParam.GAP_PARAM.Home; // 下载文件目录  
	
	private static final String ENCODING = "UTF-8"; // 文件编码方式  

	@Autowired
	@Qualifier(AppIocBean.POSTHEAD_VALIDATOR_BEAN)
	private MessageValidator validator;
	
	@Autowired
	@Qualifier(AppIocBean.BASE_INFO_SERVICEIMPL_BEAN)
	private BaseInfoService baseInfoService;
	
	@Autowired
	private SendCmDataService sendCmDataService;
	@Autowired
	private CrossNetTmpCmDataService crossNetTmpCmDataService;
	@Autowired
	private RecvCmDataService recvCmDataService;
	
	@Autowired
	@Qualifier(AppIocBean.TLQ_TRANSPORT_PIPELINE_BEAN)
	private TransportPipeline tlqTransportPileline;
	
	@Autowired
	@Qualifier(AppIocBean.RMI_TRANSPORT_PIPELINE_BEAN)
	private TransportPipeline rmiTransportPipeline;
	
	@Autowired
	@Qualifier(AppIocBean.TIMEOUT_EXPIRED_STRATEGY_BEAN)
	private ExpiredStrategy timeoutExpiredStrategy;
	
	@Autowired
	private CrossNetTmpCmDataService tmpCmDataService;
	
	@Autowired
	private DataCategoryService dataCategoryService;
	@Autowired
	private CarvedDiscsDataService carvedDiscsDataService;
	

	
	@Autowired
	private SendFileDataService sendFileDataService;
	
	@Autowired
	private CarvedDiscsUploadService carvedDiscsUploadService;
	@Autowired
	private CarvedDiscsUploadDataService carvedDiscsUploadDataService;
	@Override
	public Status validate(String posthead, String data) {
		return validator.validate(posthead, data);
	}

	
	private  TransportPipeline transportPileline=null;
	private void initTransportPileline(){
		this.transportPileline=KernelParam.tlqTransportPipelineEnable==0?rmiTransportPipeline:tlqTransportPileline;
	}
	/**
	 * 业务逻辑梳理
	 * 1.报文头验证
	 * 2.解析入库
	 *   注意点：
	 *   跨节点，节点编码前6位相同，不跨节点，节点编码前6位不相同跨节点
	 *   跨网：节点编码第七位相同不跨网，数据直接发送
	 *       发送节点第七位0，接收节点第七位1  从内网到外网  刻盘
	 *       发送节点第七位1，接收节点第七位0 从外网到内网   tlq，网闸
	 *       
	 * 入库的数据的线路
	 * 1.不跨网(0)，不跨节点(0)  数据接收后直接发送给业务系统，本节点发送
	 * 2.不跨网(0),跨节点(1)  数据接收后，通过tlq发送给接收系统，接收系统再发送给接收业务系统
	 * 3.跨网(从内网到外网1),跨节点或不跨节点(0或1) 刻盘
	 * 4.跨网(从外网到内网2) tlq发送到外网网闸节点，外网网闸节点发送到网闸，内网网闸节点接收数据，发送给接收节点
	 * 
	 * 
	 * 
	 * 信息入库，数据报文XML落地
	 */
	@Override
	public Status localStore(WebServiceContext wsc, Posthead posthead, String reqxml, String payload,ExchDataType exchDataType,String metadata) {
		String respXml = "";
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		SendResp sendResp = new SendResp();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			String ip = IpUtil.getRemoteIpAddr(wsc);
			Posthead post = (Posthead) posthead;
			RouteEntry from = post.getFrom();
			AdapterBase adapterBase=baseInfoService.getAdapterBase(from.getAdaptorcode());
			List<RouteEntry> toList = post.getToList();
			String groupId = UUIDGenerator.getUUID();
			List<SendCmData> cmDataList = new ArrayList<SendCmData>();
			sendResp.setGroupId(groupId);
			sendResp.setDatatype(adapterBase.getDataCode());
			sendResp.setDate(AppConst.dtFormat.format(now));
			List<OrderResp> orderRespList=new ArrayList<OrderResp>();
			
			boolean isStoredPayload = false;
			//先压缩，再加密
			//压缩处理
			CompressService compressService = CompressServiceFactory.createCompressService(COMPRESS_ALGORITHM.JAVA_GZIP);
			//加密处理
			EncryptService encryptService = EncryptServiceFactory.createEncryptService(ENCRYPT_ALGORITHM.DES);
			//将有所处理结果保持到头文件上
			Processes pes=new Processes();
			ProcessInfo pi=new ProcessInfo();
			
			CompressResult<String> result = compressService.compress(payload,new TurboCompressFilter<String>(ExchDataType.CM_DATA, null));
			String compress="0";
			if (result.isCommpressed()) {
				compress="1";
				payload=result.getCommpressResultObj();//压缩处理
			}
			pi.setCompress(compress);//压缩标记
			
			boolean isEncrypt=dataCategoryService.isEncode(posthead.getFrom().getDatatype());//根据数据分类判断是否加密处理
		    String seed=encryptService.randomSeed(posthead.getFrom().getNodecode()+posthead.getFrom().getAdaptorcode());//加密秘钥  节点编码+适配器编码
			EncryptResult<String> sresult=  encryptService.encryptString(seed, payload,new TurboEncryptFilter<String>(ExchDataType.CM_DATA, CrossNetType.SAME_NETWORK,isEncrypt));
			String encrypt="0";//加密标志
			if (sresult.isEncrypted()) {
				encrypt="1";
				payload=sresult.getEncryptResultObj();//加密后的字
			}
			pi.setEncrypt(encrypt);
			List<ProcessInfo> processInfos=new ArrayList<ProcessInfo>();
			processInfos.add(pi);
			pes.setProcess(processInfos);
			posthead.setProcesses(pes);
			
			
			
			//组消息
			if (toList.size() > 1) {
				SendCmData cmData = new SendCmData();
				String recvNodeList = "";
				String recvSysList = "";
				String adaptorCodeList="";
				for (RouteEntry to : toList) {
					if (to.getNodecode()!=null) {
						recvNodeList += to.getNodecode() + ",";
					}else{
						recvNodeList += "undefined"+ ",";
					}
					adaptorCodeList+=from.getAdaptorcode()+",";
				}
				recvNodeList = StrUtil.substringBeforeLast(recvNodeList, ",");
				recvSysList = StrUtil.substringBeforeLast(recvSysList, ",");
				adaptorCodeList=StrUtil.substringBeforeLast(adaptorCodeList, ",");
				cmData.setId(groupId);
				cmData.setPid("0");
				cmData.setMsgType(AppConst.MsgType.GROUP_MSG.value());
				cmData.setDataType(exchDataType.value());
				cmData.setSendNodecode(from.getNodecode());
				cmData.setRecvNodecode(recvNodeList);
				cmData.setRecvAdaptorcode(adaptorCodeList);
				cmData.setSendBusicode(adapterBase.getDataCode());//业务数据编码
				cmData.setSendAdaptorcode(from.getAdaptorcode());
				cmData.setPosthead(XstreamUtil.toXml(posthead));
				cmData.setIp(ip);
				cmData.setCreated(now);
				cmData.setMetaData(metadata);
				cmDataList.add(cmData);
			}
			
			msg = "数据接收成功";
			for (RouteEntry to : toList) {
				String id = UUIDGenerator.getUUID();
				String msgType = "";
				if (toList.size() == 1) {
					id = groupId;
					msgType = AppConst.MsgType.SINGLE_MSG.value();
				}else{
					msgType = AppConst.MsgType.SUB_MSG.value();
				}
				OrderResp orderResp = new OrderResp();
				orderResp.setOrderId(id);
				orderResp.setAdaptorcode(to.getAdaptorcode());
				orderRespList.add(orderResp);
				respXml = XstreamUtil.toXml(orderResp);
				//String crossNode = baseInfoService.isCrossNode(from.getSyscode(), to.getSyscode()) ? AppConst.YES : AppConst.NO;
				
				//String crossNet=
				

				SendCmData cmData = new SendCmData();
				//TODO
				String filePath = from.getAdaptorcode() + File.separator + AppConst.dFormat.format(now)  + File.separator + groupId + ".xml";
				cmData.setId(id);
				cmData.setPid(groupId);
				cmData.setPosthead(XstreamUtil.toXml(posthead));
				cmData.setDataType(exchDataType.value());
				cmData.setMsgType(msgType);
				//TODO BY高强，跨节点传输暂定
				if (from.getNodecode().substring(0, 6).equals(to.getNodecode().substring(0,6))) {//取前六位看是否是跨节点传输
					cmData.setCrossNode("0");
				}else{
					cmData.setCrossNode("1");
				}
				cmData.setSendNodecode(from.getNodecode());
				cmData.setSendBusicode(adapterBase.getDataCode());//业务数据编码
				cmData.setSendAdaptorcode(from.getAdaptorcode());
				cmData.setRecvNodecode(to!=null?to.getNodecode():null);
				if (from.getNodecode().substring(6, 7).equals(to.getNodecode().substring(6, 7))) {
					cmData.setCrossNet("0");
					cmData.setThroughGap("0");//不需要走网闸
					cmData.setThroughGap("0");//不需需要走网闸
				}else{
					 if (AppTagEl.isInnerNet(from.getNodecode().substring(6, 7)) && !AppTagEl.isInnerNet(to.getNodecode())) {//from为内网 to为外网
					    	cmData.setCrossNet("1");
					 }else{//from为外网，to为内网 需要走网闸
							cmData.setCrossNet("2");
							
							String gapNode=baseInfoService.getGapNode(localNode);
							 
							 if (gapNode!=null) {
								 cmData.setThroughGap("1");//需要走网闸
								 cmData.setOutGapNodeCode(gapNode);
							 }else{
								 cmData.setThroughGap("2");//需要刻盘
								 cmData.setOutGapNodeCode(null);
							 }
					}
				}
				
				cmData.setRecvAdaptorcode(from.getAdaptorcode());
				
				cmData.setPayload(filePath);
				cmData.setResp(respXml);
				
				cmData.setSendStatus(AppConst.SendStatus.READY.value());
				cmData.setNotifyStatus(AppConst.NotifyStatus.READY.value());
				cmData.setPriority(AppConst.Priority.NORMAL.value());
				cmData.setMetaData(metadata);
				cmData.setPipeline(AppConst.Pipeline.TLQ.value());
				cmData.setIp(ip);
				cmData.setCreated(now);
				cmData.setAuditPerson(from.getAuditor());//审核人
				cmData.setTrig(to.getSendTime());
				RouteLog.setLocalStore(cmData, AppConst.YES, msg,  AppConst.dtFormat.format(now));//更新路由状态
				
			
				
				
				if(!isStoredPayload){
					this.storeFile(filePath, payload);
					isStoredPayload = true;
				}
				cmDataList.add(cmData);
			}

			//数据入库
			sendCmDataService.insertBatch(cmDataList);
			sendResp.setStatus(AppConst.PostheadStatus.OK.toString());
			sendResp.setMessage(msg);
			sendResp.setOrderRespList(orderRespList);
			respXml = XstreamUtil.toXml(sendResp);
			msg = "数据接收成功";
			status.setSuccess(true);
			status.setMsg(msg);
			status.setData(respXml);
			return status;
		} catch (Exception e) {
			msg = "数据落地失败:" + e.fillInStackTrace();
			logger.error(msg, e);
			
			sendResp.setStatus(PostheadStatus.INTERNAL_SERVER_ERROR.value());
			sendResp.setMessage(msg);
			//this is Not suppose to be happend...
			try {
				respXml = XstreamUtil.toXml(sendResp);
			} catch (Exception e1) {
				logger.error(msg, e1);
			}
			status.setSuccess(false);
			status.setMsg(msg);
			status.setData(respXml);
			return status;
		}
	}
	
	
	
	/**1.不跨网(0)，不跨节点(0)  数据接收后直接发送给业务系统，本节点发送
	 * 节点内的发送，即处理不需要进行跨节点传送的消息
	 * @return
	 */
	@Override
	public Status sendDataToLocalSys() {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<SendCmData> successDataList = new ArrayList<SendCmData>(); //往管道发送成功的数据
		List<SendCmData> resendDataList = new ArrayList<SendCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<SendCmData> resendDataList1 = new ArrayList<SendCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<SendCmData> failDataList = new ArrayList<SendCmData>();    //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
		List<SendCmData> unsendDataList=new ArrayList<SendCmData>();
		try {
			//获取待发送的数据
			unsendDataList = sendCmDataService.getLocaleUnsentList();
			if (CollectionUtil.hasElement(unsendDataList)) {
				
				for (SendCmData cmData : unsendDataList) {
					msg = "数据发送至目的系统成功";
					cmData.setSendStatus(AppConst.SendStatus.LOCAL_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setRemoteSys(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.LOCAL_SENDING.value(),SendCmData.class);
				if(!status.isSuccess()){
					msg = "数据发送至目的系统失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (SendCmData cmData : unsendDataList) {
					//直接将数据发送给业务系统
					status = sendDataToReciver(cmData);
					if (status.isSuccess()) {
						cmData.setReciverSigned("" + status.getData());
						cmData.setModified(new Date());
						cmData.setSendStatus( AppConst.SendStatus.SENT.value());
						RouteLog.setRemoteSys(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
						successDataList.add(cmData);
					} else {
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if (expiredStatus.isSuccess()) {
							cmData.setModified(new Date());
							cmData.setSendStatus( AppConst.SendStatus.FAIL.value());
							RouteLog.setRemoteSys(cmData, AppConst.NO, expiredStatus.getMsg()+"   失败原因:"+status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							cmData.setModified(new Date());
							RouteLog.setRemoteSys(cmData, AppConst.NO, "消息已重发，重发原因<<"+status.getMsg()+">>", AppConst.dtFormat.format(now));//更新路由状态
							if ("2".equals(cmData.getThroughGap())) {
								cmData.setSendStatus( AppConst.SendStatus.ANALYZE_SUCESS.value());
								resendDataList1.add(cmData);
							}else{
								cmData.setSendStatus( AppConst.SendStatus.READY.value());
								resendDataList.add(cmData);
							}
							
						}
					}
					RecvCmData recvCmData=new RecvCmData();
					BeanMapper.copy(cmData, recvCmData);
					recvCmDataService.insertOrUpdate(recvCmData);
					
				}
				msg = "本节点内数据发送成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "本节点内数据发送成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "本节点内数据发送出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}finally{
			this.updateSendStatus(successDataList, AppConst.SendStatus.SENT.value(),SendCmData.class);	//发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.READY.value(),SendCmData.class);		//等待重发
			this.updateSendStatus(resendDataList1, AppConst.SendStatus.ANALYZE_SUCESS.value(),SendCmData.class);		//等待重发
			this.updateSendStatus(resendDataList, AppConst.SendStatus.FAIL.value(),SendCmData.class);  		//发送失败
		}
		return status;
	}
	
	/**
	 * 通过网闸节点刻盘
	 * @return
	 */
	public Status waitCarvedDiscsCrossNet(){
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取待发送的数据
			List<CrossNetTmpCmData> unsendDataList = tmpCmDataService.getCarvedDiscs();
			//todo 跨网生成跨网文件暂不考虑
			if (CollectionUtil.hasElement(unsendDataList)) {
				for (CrossNetTmpCmData cmData : unsendDataList) {
					msg = "等待刻盘";
					cmData.setSendStatus(AppConst.SendStatus.WAIT_CARVED_DISCS.value());
					cmData.setModified(new Date());
					RouteLog.setWaitCarvedDiscs(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
					carvedDiscsDataService.generateCarvedDiscsData(cmData);
					tmpCmDataService.update(cmData);
					
					SendCmData sendCmData=new SendCmData();
					BeanMapper.copy(cmData, sendCmData);
					if (cmData.getSendNodecode().equals(localNode.getNodeCode())) {
						sendCmDataService.update(sendCmData);
					}else{
						this.feedbackSendStatusAndRoutelog(sendCmData, sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
					}
				}
				msg = "本节点内数据发送成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "本节点内数据发送成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "本节点内数据发送出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}
		return status;
	}

	/**
	 * 从内网到外网需要刻盘
	 * @return
	 */
	public Status waitCarvedDiscs(){
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		try {
			//获取待发送的数据
			List<SendCmData> unsendDataList = sendCmDataService.getSendOutNetWorkList();
			if (CollectionUtil.hasElement(unsendDataList)) {
				for (SendCmData cmData : unsendDataList) {
					msg = "数据等待刻盘";
					cmData.setSendStatus(AppConst.SendStatus.WAIT_CARVED_DISCS.value());
					cmData.setModified(new Date());
					RouteLog.setWaitCarvedDiscs(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.WAIT_CARVED_DISCS.value(),SendCmData.class);
				
				if(!status.isSuccess()){
					msg = "数据等待刻盘失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (SendCmData cmData : unsendDataList) {
					carvedDiscsDataService.generateCarvedDiscsData(cmData);
					sendCmDataService.update(cmData);
				}
				
			
				msg = "本节点内数据发送成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "本节点内数据发送成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "本节点内数据发送出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}
		return status;
	}
	
	/**
	 * 从内网到外网需要刻盘
	 * @return
	 */
	public Status carvedDiscs(CmData cmdata){
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			if (cmdata instanceof SendCmData) {
				SendCmData sendCmData=(SendCmData) cmdata;
				msg = "已刻盘";
				sendCmData.setSendStatus(AppConst.SendStatus.CARVED_DISCS.value());
				sendCmData.setModified(new Date());
				RouteLog.setCarvedDiscs(sendCmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				RecvCmData recvCmData=new RecvCmData();
				BeanMapper.copy(sendCmData, recvCmData);
				recvCmDataService.update(recvCmData);
				sendCmDataService.update(sendCmData);
			}else if(cmdata instanceof RecvCmData){
				RecvCmData recvCmData=(RecvCmData) cmdata;
				msg = "已刻盘";
				recvCmData.setSendStatus(AppConst.SendStatus.CARVED_DISCS.value());
				recvCmData.setModified(new Date());
				RouteLog.setWaitCarvedDiscs(recvCmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				SendCmData sendCmData=new SendCmData();
				BeanMapper.copy(recvCmData, sendCmData);
				recvCmDataService.update(recvCmData);
				sendCmDataService.update(sendCmData);
			}else if (cmdata instanceof CrossNetTmpCmData) {
				CrossNetTmpCmData tmpCmData=(CrossNetTmpCmData) cmdata;
				msg = "已刻盘";
				tmpCmData.setSendStatus(AppConst.SendStatus.CARVED_DISCS.value());
				tmpCmData.setModified(new Date());
				RouteLog.setWaitCarvedDiscs(tmpCmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				SendCmData sendCmData=new SendCmData();
				BeanMapper.copy(tmpCmData, sendCmData);
				if (localNode.getNodeCode().equals(tmpCmData.getSendNodecode())) {//
					tmpCmDataService.update(tmpCmData);
					sendCmDataService.update(sendCmData);
				}else{
					tmpCmDataService.update(tmpCmData);
					this.feedbackSendStatusAndRoutelog(sendCmData, sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
				}
			}
				msg = "刻盘成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
		} catch (Exception e) {
			msg = "刻盘出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}
		return status;
	}
	
	
	
	/**
	 * 发送到外网网闸节点，或者中央节点
	 */
	public Status sendDataToOuterSendPipeline() {
		initTransportPileline();
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<SendCmData> successDataList = new ArrayList<SendCmData>(); //往管道发送成功的数据
		List<SendCmData> resendDataList = new ArrayList<SendCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<SendCmData> failDataList = new ArrayList<SendCmData>();    //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取需要从外网到内网传输的列表
			//获取待发送的数据
			List<SendCmData> outToInnerList = sendCmDataService.getSendInnerNetWorkList();
			if (CollectionUtil.hasElement(outToInnerList)) {
				
				for (SendCmData cmData : outToInnerList) {
					msg = "数据发送至外网中转站成功";
					cmData.setSendStatus(AppConst.SendStatus.LOCAL_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setSendDataToOuterSendPipeline(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(outToInnerList, AppConst.SendStatus.LOCAL_SENDING.value(),SendCmData.class);
				if(!status.isSuccess()){
					msg = "数据发送至传输管道失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (SendCmData cmData : outToInnerList) {
					//将数据发送至对应的传输管道中,数据cmdata,from:本地节点，to,网闸节点  队列类型:gapEntrepot
					if (localNode.getNodeCode().equals(cmData.getOutGapNodeCode())) {
						this.outerEntrepotStore(cmData);
					}else{
						status = transportPileline.sendData(cmData, localNode.getNodeCode(), cmData.getOutGapNodeCode(), ExchageLifecycle.gapEntrepot);
					}
					String tlqMsg = status.getMsg();
					if (status.isSuccess()) {
						cmData.setModified(new Date());
						RouteLog.setSendDataToOuterSendPipeline(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
						successDataList.add(cmData);
					} else {
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if (expiredStatus.isSuccess()) {
							cmData.setModified(new Date());
							RouteLog.setSendDataToOuterSendPipeline(cmData, AppConst.NO,expiredStatus.getMsg()+"  失败原因"+ status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							cmData.setModified(new Date());
							RouteLog.setSendDataToOuterSendPipeline(cmData, AppConst.NO, tlqMsg, AppConst.dtFormat.format(now));//更新路由状态
							resendDataList.add(cmData);
						}
					}
				}
			  }
			
			
		}catch (Exception e) {
			msg = "数据发送至传输管道出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}finally{
			this.updateSendStatus(successDataList, AppConst.SendStatus.LOCAL_SENT.value(),SendCmData.class);	//发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.READY.value(),SendCmData.class);		//等待重发
			this.updateSendStatus(failDataList, AppConst.SendStatus.FAIL.value(),SendCmData.class);  		//发送失败
		}
		return status;
	}
	
	
	public Status outerEntrepotStore(SendCmData sendCmData) {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		try {
			msg = "数据在外网中转站仓库落地成功";
			RouteLog.setOuterEntrepotStore(sendCmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
			sendCmData.setModified(now);
			sendCmData.setSendStatus(AppConst.SendStatus.OUTER_ENTREPOT_READY.value());
			CrossNetTmpCmData tmpCmData = new CrossNetTmpCmData();
			BeanMapper.copy(sendCmData, tmpCmData);
			
			tmpCmDataService.insertOrUpdate(tmpCmData);

			status = this.storeFile(tmpCmData.getPayload(), tmpCmData.getPayloadContent());
			if (!status.isSuccess()) {
				msg = "数据在外网中转站仓库落地出现异常:" + status.getMsg();
				status.setSuccess(false);
				status.setMsg(msg);
				
				RouteLog.setOuterEntrepotStore(sendCmData, AppConst.NO, msg, AppConst.dtFormat.format(now));
				sendCmData.setModified(now);
				
				RouteLog.setOuterEntrepotStore(tmpCmData, AppConst.NO, msg, AppConst.dtFormat.format(now));
				tmpCmData.setModified(now);
				
				
				//如果文件存储失败，则更新路由状态
				tmpCmDataService.updateIgnoreNull(tmpCmData);
			}
		} catch (Exception e) {
			msg = "数据在外网中转站仓库落地出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
			try {
				RouteLog.setOuterEntrepotStore(sendCmData, AppConst.NO, msg, AppConst.dtFormat.format(now));
				sendCmData.setModified(now);
			} catch (Exception ex) {
				//ignored...
			}
		} finally {
			//将数据信息置空，至传日志信息
			sendCmData.setPayloadContent(null);
			status.setSuccess(true);
			status.setMsg(msg);
			status.setData(sendCmData);
			if (sendCmData.getSendNodecode().equals(sendCmData.getOutGapNodeCode())) {
				try {
					this.sendCmDataService.update(sendCmData);
				} catch (ServiceException e) {
					//ignored...
				}
			}else if(AppConst.Pipeline.TLQ.value().equals(sendCmData.getPipeline())){
				//将发送状态和路由信息通知源节点 (发送节点)将数据发送至对应的传输管道中,数据cmdata,from:本地节点，to,网闸节点  队列类型:gapEntrepot
				this.feedbackSendStatusAndRoutelog(sendCmData, sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
			}
		}
		status.setMsg("外网中转存储");
		status.setSuccess(true);
		return status;
	}
	
	
	
	/**
	 * 定时任务，将文件发送至外网网闸的FTP目录
	 * @return
	 */
	public Status outerGAP() {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<CrossNetTmpCmData> successDataList = new ArrayList<CrossNetTmpCmData>(); //往ftp server发送成功的数据
		List<CrossNetTmpCmData> resendDataList = new ArrayList<CrossNetTmpCmData>(); //待重发的数据，ftp server发送失败时将进行重发
		List<CrossNetTmpCmData> failDataList = new ArrayList<CrossNetTmpCmData>(); //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
		BufferedWriter fw = null;
		List<File> tempFiles = new ArrayList<File>();
		//获取待发送的网闸的数据
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			List<CrossNetTmpCmData> unsendDataList = tmpCmDataService.getLocaleGapUnsentList();
			//如果unsendDataList 不为空
			if (CollectionUtil.hasElement(unsendDataList)) {

				//更新状态 为 发送到网闸
				for (CrossNetTmpCmData cmData : unsendDataList) {
					msg = "数据发送至外网网闸的FTP目录成功";
					cmData.setSendStatus(AppConst.SendStatus.OUTER_ENTREPOT_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setOuterGAP(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));//与发送文件到外网网闸的日志信息
				}

				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.OUTER_ENTREPOT_SENDING.value(),CrossNetTmpCmData.class);

				//将数据上传到FTP服务器
				for (CrossNetTmpCmData tmpCmData : unsendDataList) {
					String filePath = AppConst.CMDATA_STORED_DIR + File.separator + tmpCmData.getPayload();
					File file = new File(filePath);
					if (!file.exists()) {
						msg = "数据发送至外网网闸[FTP]失败：数据报文文件[" + filePath + "]找不到";
						tmpCmData.setModified(new Date());
						tmpCmData.setSendStatus(AppConst.SendStatus.FAIL.value());
						RouteLog.setOuterGAP(tmpCmData, AppConst.NO, msg,
								AppConst.dtFormat.format(now));//更新路由状态
						failDataList.add(tmpCmData);
						continue;
					}
					tmpCmData.setPayloadContent(FileUtils.readFileToString(file));
					//将unsendDataList封装成json数据
					String jsonStr = JsonUtil.toJson(tmpCmData);
					//将json数据生成文件
					String path =AppConst.APP_GAP_FTP_OUT_LOCALFTPPUT;//获取临时生成的文件的目录
					String suffix =AppConst.APP_GAP_TEMP_FILE;//获取临时生成的文件的后缀
					file = new File(path + localNode.getNodeCode()+"_"+ tmpCmData.getId() + suffix);//生成的临时文件   主键id+".txt"
					if (!file.getParentFile().exists()) {
						file.getParentFile().mkdirs();
					}
					fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8"));
					fw.write(jsonStr);
					fw.flush();
					tempFiles.add(file);//保存生成的临时文件，最后要删除
					//将文件发送到ftp 服务器
					status = FtpUtil.upload(new FTPClient(),inIp,
							inUserName,
							inPassword,
							inPort, file,
							inOutput+File.separator + file.getName());

					if (status.isSuccess()) {
						tmpCmData.setModified(new Date());
						tmpCmData.setSendStatus(AppConst.SendStatus.OUTER_ENTREPOT_SUCCESS.value());
						tmpCmData.setSenderSigned(StrUtil.fixNull(status.getData()));
						RouteLog.setOuterGAP(tmpCmData, AppConst.YES, status.getMsg(),
								AppConst.dtFormat.format(now));//更新路由状态
						successDataList.add(tmpCmData);
					} else {
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(tmpCmData.getCreated());
						if (expiredStatus.isSuccess()) {
							tmpCmData.setModified(new Date());
							tmpCmData.setSendStatus(AppConst.SendStatus.FAIL.value());
							tmpCmData.setThroughGap("2");//转为刻盘
							RouteLog.setOuterGAP(tmpCmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+status.getMsg(),
									AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(tmpCmData);
						} else {
							tmpCmData.setModified(new Date());
							tmpCmData.setSendStatus(AppConst.SendStatus.OUTER_ENTREPOT_READY.value());
							RouteLog.setOuterGAP(tmpCmData, AppConst.NO, status.getMsg(),
									AppConst.dtFormat.format(now));//更新路由状态
							resendDataList.add(tmpCmData);
						}
					}

					//将发送结果通知源节点(发送节点)
					SendCmData sendCmData = new SendCmData();
					BeanMapper.copy(tmpCmData, sendCmData);
					
					//将发送状态和路由信息通知源节点 (发送节点)将数据发送至对应的传输管道中,数据cmdata,from:本地节点，to,网闸节点  队列类型:gapEntrepot
					if (sendCmData.getSendNodecode().equals(sendCmData.getOutGapNodeCode())) {
						sendCmDataService.update(sendCmData);
					}else{
						this.feedbackSendStatusAndRoutelog(sendCmData, sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
					}
				}

				msg = "通知数据发送系统成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			} else {
				msg = "数据投递结果反馈给网闸节点成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "本节点内数据发送出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		} finally {
			this.updateSendStatus(successDataList, AppConst.SendStatus.OUTER_ENTREPOT_SUCCESS.value(), CrossNetTmpCmData.class); //发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.OUTER_ENTREPOT_READY.value(), CrossNetTmpCmData.class); //等待重发
			this.updateSendStatus(failDataList, AppConst.SendStatus.FAIL.value(), CrossNetTmpCmData.class); //发送失败
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					logger.error(e);
				}
			}

			//删除临时生成的文件
			for (File file : tempFiles) {
				if (file.exists()) {
					boolean flag = file.delete();
					if (flag) {
						logger.info("删除临时文件[" + file.getName() + "]成功");
					} else {
						logger.info("删除临时文件[" + file.getName() + "]失败");
					}
				}
			}
		}
		return status;
	}
	
	/**
	 * 内网网闸节点保存入库
	 * @return
	 */
	public synchronized Status  innerEntrepotStore() {
		String msg = "";
		Status status = Status.getInstance();
		FTPClient ftpClient = new FTPClient();
		ftpClient.setConnectTimeout(AppConst.FTP_TIMEOUT);
		FileOutputStream fos = null;
		NodeInfo localNode=null;
		// 登录FTP服务器  
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			if(!NetUtil.canConnect(inIp, inPort))return null;
			ftpClient.connect(inIp, inPort);
			
			ftpClient.login(inUserName, inPassword);
			String fileName = "";
			// FTP服务器要被下载的文件(路径加文件名)
			String remoteFileName = "";
			// 下载后在本地生成的文件(路径加文件名) 
			File localFile = null;
			// 把符合条件的文件下载到本地 
			if (inOutput!=null && !"".equals(inOutput)) {
				ftpClient.changeWorkingDirectory(inOutput);
			}
			File temp=new File(AppConst.APP_GAP_FTP_INNER_LOCALFTPPUT);//创建临时目录
			if (!temp.exists()) {
				temp.mkdirs();
			}
			
			FTPFile[] files = ftpClient.listFiles();
			for (FTPFile file : files) {
				if (file.isFile() && file.getName().endsWith(".json")) {
					fileName = file.getName();
					if (!fileName.substring(0, 6).equals(localNode.getNodeCode().substring(0, 6))) {
						continue;
					}
					remoteFileName = fileName;
					localFile = new File(temp ,fileName);
					fos = new FileOutputStream(localFile);
					ftpClient.setBufferSize(1024*1024*10);
					ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
					ftpClient.retrieveFile(fileName, fos);
					fos.flush();
					
					String str=FileUtils.readFileToString(localFile);
					CrossNetTmpCmData tmpCmData = JsonUtil.toObject(str, CrossNetTmpCmData.class);
					tmpCmData.setSendStatus(AppConst.SendStatus.INNER_ENTREPOT_READY.value());
					RouteLog.setInnerGAP(tmpCmData, AppConst.YES, "网闸文件下载", AppConst.dFormat.format(new Date()));
					RouteLog.setInnerEntrepotStore(tmpCmData, AppConst.YES, "内网网闸节点存储", AppConst.dFormat.format(new Date()));
					
					status = this.storeFile(tmpCmData.getPayload(), tmpCmData.getPayloadContent());
					if (!status.isSuccess()) {
						status.setSuccess(false);
						status.setMsg(msg);
						RouteLog.setInnerEntrepotStore(tmpCmData, AppConst.NO, msg, AppConst.dtFormat.format(new Date()));
						tmpCmData.setModified(new Date());
						RouteLog.setInnerEntrepotStore(tmpCmData, AppConst.NO, msg, AppConst.dtFormat.format(new Date()));
						tmpCmData.setModified(new Date());
						tmpCmData.setSendStatus(AppConst.SendStatus.FAIL.value());
					}
					tmpCmData.setInnerGapNodeCode(localNode.getNodeCode());
					tmpCmDataService.insertOrUpdate(tmpCmData);
					
					localFile.delete();
					
					ftpClient.deleteFile(remoteFileName);
				}
			}
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "下载出现异常:" + e.fillInStackTrace();
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		} finally {
			// 关闭连接  
			IOUtils.closeQuietly(fos);
			try {
				if (fos!=null) {
					fos.close();
				}
				ftpClient.disconnect();
			} catch (IOException e) {
				logger.error(msg, e);
				msg = "下载出现异常:" + e.fillInStackTrace();
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
		}
		return status;
	}
	
	
	public Status sendDataToInnerSendPipeline() {
		initTransportPileline();
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<CrossNetTmpCmData> successDataList = new ArrayList<CrossNetTmpCmData>(); //往管道发送成功的数据
		List<CrossNetTmpCmData> resendDataList = new ArrayList<CrossNetTmpCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<CrossNetTmpCmData> failDataList = new ArrayList<CrossNetTmpCmData>();    //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
	    NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取待发送的数据
			List<CrossNetTmpCmData> unsendDataList = tmpCmDataService.getInnerEntrepotUnsentList();
			if (CollectionUtil.hasElement(unsendDataList)) {
				
				for (CrossNetTmpCmData cmData : unsendDataList) {
					msg = "数据发送至传输管道成功";
					cmData.setSendStatus(AppConst.SendStatus.INNER_ENTREPOT_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setInnerSendPipeline(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.OUTER_ENTREPOT_SENDING.value(),CrossNetTmpCmData.class);
				
				if(!status.isSuccess()){
					msg = "数据发送至传输管道失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (CrossNetTmpCmData cmData : unsendDataList) {
					//将数据发送至对应的传输管道中
					/*String pipeline = cmData.getPipeline();
					if (AppConst.Pipeline.HTTP.value().equals(pipeline)) {
						status = httpTransportPipeline.sendDataToOuterSendPipeline(cmData);
						if (status.isSuccess()) {
							SendCmData cmDataResp = (SendCmData) status.getData();
							cmData.setRoutelog(cmDataResp.getRoutelog());
						}
					}
					
					if (AppConst.Pipeline.TLQ.value().equals(pipeline)) {
					}*/
					
					if (localNode.getNodeCode().equals(cmData.getRecvNodecode())) {
						SendCmData sendCmData=new SendCmData();
						BeanMapper.copy(cmData, sendCmData);
						this.remoteStore(sendCmData);
					}else{
						SendCmData sendCmData=new SendCmData();
						BeanMapper.copy(cmData, sendCmData);
						status = transportPileline.sendData(sendCmData,localNode.getNodeCode(),cmData.getRecvNodecode(),ExchageLifecycle.remoteStoreTmp);
					}
					
					if (status.isSuccess()) {
						cmData.setModified(new Date());
						RouteLog.setInnerSendPipeline(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
						successDataList.add(cmData);
					} else {
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if (expiredStatus.isSuccess()) {
							cmData.setModified(new Date());
							RouteLog.setInnerSendPipeline(cmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							cmData.setModified(new Date());
							RouteLog.setInnerSendPipeline(cmData, AppConst.NO, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							resendDataList.add(cmData);
						}
					}
				}
				
				msg = "数据发送至传输管道成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "数据发送至传输管道成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "数据发送至传输管道出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}finally{
			this.updateSendStatus(successDataList, AppConst.SendStatus.INNER_ENTREPOT_SEND.value(),CrossNetTmpCmData.class);	//发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.INNER_ENTREPOT_READY.value(),CrossNetTmpCmData.class);	//等待重发
			this.updateSendStatus(failDataList, AppConst.SendStatus.FAIL.value(),CrossNetTmpCmData.class);  	//发送失败
		}
		return status;
	}

	
	
	/**
	 * 此方法逻辑
	 * 1、查找发送状态为待发送的数据列表
	 * 2、锁定这批数据:将这批待发送的数据的状态更新为“发送中”
	 * 3、遍历这个列表里面的数据，根据数据的管道类型发送至不同的管道中
	 * 4、处理发送结果
	 * 		4.1:发送成功，更新路由状态
	 *      4.2：发送失败，更新路由状态
	 *      	4.2.1：消息没失效？等待重发
	 *          4.2.2：消息失效？将状态值为发送失败
	 */
	@Override
	public Status sendDataToPipline() {
		initTransportPileline();
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<SendCmData> successDataList = new ArrayList<SendCmData>(); //往管道发送成功的数据
		List<SendCmData> resendDataList = new ArrayList<SendCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<SendCmData> resendDataList1 = new ArrayList<SendCmData>();  //待重发的数据，管道发送失败时将进行重发
		List<SendCmData> failDataList = new ArrayList<SendCmData>();    //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取待发送的数据
			List<SendCmData> unsendDataList = sendCmDataService.getCrossNodeUnsentList();
			if (CollectionUtil.hasElement(unsendDataList)) {
				
				for (SendCmData cmData : unsendDataList) {
					msg = "数据发送至传输管道成功";
					cmData.setSendStatus(AppConst.SendStatus.LOCAL_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setLocalPipeline(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.LOCAL_SENDING.value(),SendCmData.class);
				
				if(!status.isSuccess()){
					msg = "数据发送至传输管道失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (SendCmData cmData : unsendDataList) {
					/*String pipeline = cmData.getPipeline();
					if (AppConst.Pipeline.HTTP.value().equals(pipeline)) {
						status = httpTransportPipeline.sendData(cmData);
						if (status.isSuccess()) {
							SendCmData cmDataResp = (SendCmData) status.getData();
							cmData.setRoutelog(cmDataResp.getRoutelog());
						}
					}
					if (AppConst.Pipeline.TLQ.value().equals(pipeline)) {
						status = transportPileline.sendData(cmData);
					}*/
					
					//将数据发送至对应的传输管道中
					status = transportPileline.sendData(cmData,localNode.getNodeCode(),cmData.getRecvNodecode(),ExchageLifecycle.remoteStore);
					String tlqMsg = status.getMsg();
					if (status.isSuccess()) {
						cmData.setModified(new Date());
						RouteLog.setLocalPipeline(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
						successDataList.add(cmData);
					} else {
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if (expiredStatus.isSuccess()) {
							cmData.setModified(new Date());
							RouteLog.setLocalPipeline(cmData, AppConst.NO,expiredStatus.getMsg()+"  失败原因:"+ status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							
							cmData.setModified(new Date());
							RouteLog.setLocalPipeline(cmData, AppConst.NO, tlqMsg, AppConst.dtFormat.format(now));//更新路由状态
							if ("2".equals(cmData.getThroughGap())) {
								cmData.setSendStatus( AppConst.SendStatus.ANALYZE_SUCESS.value());
								resendDataList1.add(cmData);
							}else{
								cmData.setSendStatus( AppConst.SendStatus.READY.value());
								resendDataList.add(cmData);
							}
						}
					}
				}
				
				msg = "数据发送至传输管道成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "数据发送至传输管道成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "数据发送至传输管道出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}finally{
			this.updateSendStatus(successDataList, AppConst.SendStatus.LOCAL_SENT.value(),SendCmData.class);	//发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.READY.value(),SendCmData.class);		//等待重发
			this.updateSendStatus(resendDataList1, AppConst.SendStatus.ANALYZE_SUCESS.value(),SendCmData.class);		//等待重发
			this.updateSendStatus(failDataList, AppConst.SendStatus.FAIL.value(),SendCmData.class);  		//发送失败
		}
		return status;
	}

	@Override
	public Status remoteStore(SendCmData sendCmData) {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		NodeInfo localNode=null;
		RecvCmData recvCmData=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			recvCmData = new RecvCmData();
			BeanMapper.copy(sendCmData, recvCmData);

			status = this.storeFile(recvCmData.getPayload(), recvCmData.getPayloadContent());
			if (!status.isSuccess()) {
				msg = "数据在远程仓库落地出现异常:" + status.getMsg();
				status.setSuccess(false);
				status.setMsg(msg);
				RouteLog.setRemoteStore(recvCmData, AppConst.NO, msg, AppConst.dtFormat.format(now));
				recvCmData.setModified(now);
				recvCmData.setSendStatus(AppConst.SendStatus.FAIL.value());
				//如果文件存储失败，则更新路由状态
				recvCmDataService.insertOrUpdate(recvCmData);
			}else{
				msg = "数据在远程仓库落地成功";
				RouteLog.setRemoteStore(recvCmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				recvCmData.setModified(now);
				recvCmData.setSendStatus(AppConst.SendStatus.REMOTE_READY.value());
				recvCmDataService.insertOrUpdate(recvCmData);
			}
		} catch (Exception e) {
			BeanMapper.copy(recvCmData,sendCmData);
		} finally {
			 BeanMapper.copy(recvCmData,sendCmData);
			//将数据信息置空，至传日志信息
			sendCmData.setPayloadContent(null);
			status.setSuccess(true);
			status.setMsg(msg);
			status.setData(sendCmData);
			if(AppConst.Pipeline.TLQ.value().equals(sendCmData.getPipeline())){
				  	if (sendCmData.getOutGapNodeCode()==null || "".equals(sendCmData.getOutGapNodeCode())) {
						//将发送结果通知源节点
						this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
					}else if(sendCmData.getOutGapNodeCode()!=null && sendCmData.getCrossNet().equals(AppConst.CrossNetType.INNER_OUT_NETWORK.value())){
						this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getOutGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
					}else if(sendCmData.getInnerGapNodeCode()!=null && sendCmData.getThroughGap().equals("2") && sendCmData.getCrossNet().equals(AppConst.CrossNetType.OUT_INNER_NETWORK.value())){
						this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getInnerGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
					}else if(localNode.getNodeCode().equals(sendCmData.getRecvNodecode()) && localNode.getNodeCode().equals(sendCmData.getInnerGapNodeCode())){
						CrossNetTmpCmData tmp=new CrossNetTmpCmData();
						BeanMapper.copy(sendCmData, tmp);
						try {
							crossNetTmpCmDataService.insertOrUpdate(tmp);
						} catch (ServiceException e) {
							logger.error("更新失败:"+e);
						}
					}else{//返回网闸节点
						this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getInnerGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelogToTmp);
					}	
			}
		}
		status.setSuccess(true);
		status.setMsg("调用远程存储成功");
		return status;
	}

	@Override
	public Status notifyReceiver() {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<RecvCmData> successDataList = new ArrayList<RecvCmData>(); //往目的业务系统发送数据
		List<RecvCmData> resendDataList = new ArrayList<RecvCmData>();  //待重发的数据，往业务系统发送失败时，下次要进行重发
		List<RecvCmData> failDataList = new ArrayList<RecvCmData>();    //发送失败的数据，只要这条消息符合失效的策略，则判定发送失败
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取待发送的数据
			List<RecvCmData> unsendDataList = recvCmDataService.getUnsentList();
			if (CollectionUtil.hasElement(unsendDataList)) {
				
				for (RecvCmData cmData : unsendDataList) {
					msg = "数据成功发送至业务系统";
					cmData.setSendStatus(AppConst.SendStatus.REMOTE_SENDING.value());
					cmData.setModified(new Date());
					RouteLog.setRemoteSys(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}
				
				//将发送状态修改为发送中，并更新相关的路由日志
				status = this.updateSendStatus(unsendDataList, AppConst.SendStatus.REMOTE_SENDING.value(),RecvCmData.class);
				
				if(!status.isSuccess()){
					msg = "数据发送至业务系统失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				for (RecvCmData cmData : unsendDataList) {
					try {
						//给业务系统发送数据
						status = sendDataToReciver(cmData);
						if (status.isSuccess()) {
							cmData.setModified(new Date());
							cmData.setSendStatus(AppConst.SendStatus.SENT.value());
							cmData.setReciverSigned(StrUtil.fixNull(status.getData()));
							RouteLog.setRemoteSys(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							successDataList.add(cmData);
						} else {
							//判断消息是否过期
							Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
							if(expiredStatus.isSuccess()){
								cmData.setModified(new Date());
								cmData.setSendStatus(AppConst.SendStatus.FAIL.value());
								RouteLog.setRemoteSys(cmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
								failDataList.add(cmData);
							}else{
								cmData.setModified(new Date());
								cmData.setSendStatus(AppConst.SendStatus.REMOTE_READY.value());
								RouteLog.setRemoteSys(cmData, AppConst.NO, "消息已重发，重发原因<<"+status.getMsg()+">>", AppConst.dtFormat.format(now));//更新路由状态
								resendDataList.add(cmData);
							}
						}
					} catch (Exception e) {
						msg = "给业务系统["+cmData.getRecvAdaptorcode()+"]发送数据过程出现异常:" + e.fillInStackTrace();
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if(expiredStatus.isSuccess()){
							cmData.setModified(new Date());
							cmData.setSendStatus(AppConst.SendStatus.FAIL.value());
							RouteLog.setRemoteSys(cmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+msg, AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							cmData.setModified(new Date());
							cmData.setSendStatus(AppConst.SendStatus.REMOTE_READY.value());
							RouteLog.setRemoteSys(cmData, AppConst.NO, "消息已重发，重发原因<<"+msg+">>", AppConst.dtFormat.format(now));//更新路由状态
							resendDataList.add(cmData);
						}
						logger.error(msg, e);
					} finally {
						SendCmData sendCmData = new SendCmData();
						BeanMapper.copy(cmData, sendCmData);
						//将发送结果通知源节点
						if (localNode.getNodeCode().equals(sendCmData.getSendNodecode())) {//本节点的发送
						   this.sendCmDataService.update(sendCmData);
						}else if(localNode.getNodeCode().equals(sendCmData.getRecvNodecode()) && localNode.getNodeCode().equals(sendCmData.getInnerGapNodeCode())){
							CrossNetTmpCmData tmp=new CrossNetTmpCmData();
							BeanMapper.copy(cmData, tmp);
							crossNetTmpCmDataService.insertOrUpdate(tmp);
						}else if(sendCmData.getCrossNode().equals("1") && sendCmData.getCrossNet().equals("0")){//同网跨节点
							this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getSendNodecode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
						}else if(sendCmData.getCrossNet().equals(AppConst.CrossNetType.OUT_INNER_NETWORK.value())){
							if ("2".equals(sendCmData.getThroughGap())) {
								this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getInnerGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
							}else{
								this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getInnerGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelogToTmp);
							}
						}else if(sendCmData.getOutGapNodeCode()!=null && sendCmData.getCrossNet().equals(AppConst.CrossNetType.INNER_OUT_NETWORK.value())){
							this.feedbackSendStatusAndRoutelog(sendCmData,sendCmData.getOutGapNodeCode(),ExchageLifecycle.feedbackSendStatusAndRoutelog);
						}
					}
				}
				
				msg = "数据发送业务系统成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}else{
				msg = "数据发送业务系统成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "数据发送业务系统出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}finally{
			this.updateSendStatus(successDataList, AppConst.SendStatus.SENT.value(),RecvCmData.class);	//发送成功
			this.updateSendStatus(resendDataList, AppConst.SendStatus.REMOTE_READY.value(),RecvCmData.class);//等待重发
			this.updateSendStatus(failDataList, AppConst.SendStatus.FAIL.value(),RecvCmData.class);  		//发送失败
		}
	}

	@Override
	public Status notifySender() {
		String msg = "";
		Status status = Status.getInstance();
		Date now = new Date();
		List<SendCmData> successDataList = new ArrayList<SendCmData>(); //成功通知发送者的数据
		List<SendCmData> resendDataList = new ArrayList<SendCmData>(); //本次通知失败，下次要进行重新通知
		List<SendCmData> failDataList = new ArrayList<SendCmData>(); //本次通知失败，且这条消息符合失效的策略，则判定通知失败
		List<SendCmData> toBeNotifyList=new ArrayList<SendCmData>();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			//获取待发送的数据
			toBeNotifyList= sendCmDataService.getToBeNotifyList();
			if (CollectionUtil.hasElement(toBeNotifyList)) {

				for (SendCmData cmData : toBeNotifyList) {
					msg = "数据投递结果反馈给发送系统成功";
					cmData.setNotifySender(AppConst.NotifyStatus.NOTIFYING.value());
					cmData.setModified(new Date());
					RouteLog.setLocalSys(cmData, AppConst.YES, msg, AppConst.dtFormat.format(now));
				}

				//将发送状态修改为发送中，并更新相关的路由日志
				sendCmDataService.updateNotifyStatus(toBeNotifyList, AppConst.NotifyStatus.NOTIFYING.value());
				/*if (i != toBeNotifyList.size()) {
					msg = "数据投递结果反馈给发送系统失败：" + status.getMsg();
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}*/

				for (SendCmData cmData : toBeNotifyList) {
					try {
						//给业务系统发送数据
						status = sendResultToSender(cmData);
						
						if (status.isSuccess()) {
							cmData.setModified(new Date());
							cmData.setNotifyStatus(AppConst.NotifyStatus.NOTIFIED.value());
							cmData.setSenderSigned(StrUtil.fixNull(status.getData()));
							RouteLog.setLocalSys(cmData, AppConst.YES, status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
							successDataList.add(cmData);
						} else {
							//判断消息是否过期
							Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
							if(expiredStatus.isSuccess()){
								cmData.setModified(new Date());
								cmData.setNotifyStatus(AppConst.NotifyStatus.FAIL.value());
								RouteLog.setLocalSys(cmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+status.getMsg(), AppConst.dtFormat.format(now));//更新路由状态
								failDataList.add(cmData);
							}else{
								cmData.setModified(new Date());
								cmData.setNotifyStatus(AppConst.NotifyStatus.READY.value());
								RouteLog.setLocalSys(cmData, AppConst.NO,"消息已重发，重发原因<<"+status.getMsg()+">>" , AppConst.dtFormat.format(now));//更新路由状态
								resendDataList.add(cmData);
							}
						}
					} catch (Exception e) {
						msg = "给发送适配器[" + cmData.getSendAdaptorcode() + "]反馈投递结果过程出现异常:" + e.fillInStackTrace();
						//判断消息是否过期
						Status expiredStatus = timeoutExpiredStrategy.isExpired(cmData.getCreated());
						if(expiredStatus.isSuccess()){
							cmData.setModified(new Date());
							cmData.setNotifyStatus(AppConst.NotifyStatus.FAIL.value());
							RouteLog.setLocalSys(cmData, AppConst.NO, expiredStatus.getMsg()+"  失败原因:"+msg, AppConst.dtFormat.format(now));//更新路由状态
							failDataList.add(cmData);
						}else{
							cmData.setModified(new Date());
							cmData.setNotifyStatus(AppConst.NotifyStatus.READY.value());
							RouteLog.setLocalSys(cmData, AppConst.NO,"消息已重发，重发原因<<"+msg+">>" , AppConst.dtFormat.format(now));//更新路由状态
							resendDataList.add(cmData);
						}
						logger.error(msg, e);
					} finally {
							//将发送结果通知源节点
							if (localNode.getNodeCode().equals(cmData.getRecvNodecode())) {//本节点的发送
								RecvCmData recvCmData=new RecvCmData();
								BeanMapper.copy(cmData, recvCmData);
							   this.recvCmDataService.update(recvCmData);
							}else if(!localNode.getNodeCode().equals(cmData.getRecvNodecode()) && cmData.getCrossNet().equals("0") && cmData.getCrossNode().equals("1")){//同网跨节点
								this.feedbackNotifyStatusAndRoutelog(cmData,cmData.getRecvNodecode(),ExchageLifecycle.feedbackNotifyStatusAndRoutelog);
							}else if(!localNode.getNodeCode().equals(cmData.getRecvNodecode()) && cmData.getCrossNet().equals(AppConst.CrossNetType.OUT_INNER_NETWORK)){
								this.feedbackNotifyStatusAndRoutelog(cmData,cmData.getOutGapNodeCode(),ExchageLifecycle.feedbackNotifyStatusAndRoutelogTmp);
							}
					}
				}

				msg = "通知数据发送系统成功";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			} else {
				msg = "数据投递结果反馈给发送系统成功：没有需要发送的数据";
				status.setSuccess(true);
				status.setMsg(msg);
				return status;
			}
		} catch (Exception e) {
			msg = "数据投递结果反馈给发送系统出现异常:" + e.fillInStackTrace();
			logger.error(msg, e);
			status.setSuccess(false);
			status.setMsg(msg);
		}finally{
			try {
				sendCmDataService.updateNotifyStatus(successDataList, AppConst.NotifyStatus.NOTIFIED.value()); //通知成功
				sendCmDataService.updateNotifyStatus(resendDataList, AppConst.NotifyStatus.READY.value()); //等待重发
				sendCmDataService.updateNotifyStatus(failDataList, AppConst.NotifyStatus.FAIL.value()); //通知失败
			} catch (NiceException e) {
				msg = "数据投递结果反馈给发送系统出现异常:" + e.fillInStackTrace();
				logger.error(msg, e);
			} 
		}
		return status;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Status updateSendStatus(List dataList, String status,Class clazz) {
		String msg = "";
		Status result = Status.getInstance();
		try {
			if(clazz.equals(SendCmData.class)){
				sendCmDataService.updateSendStatus((List<SendCmData>) dataList, status);
			}else if(clazz.equals(CrossNetTmpCmData.class)){
				crossNetTmpCmDataService.updateSendStatus((List<CrossNetTmpCmData>) dataList, status);
			}else{
				recvCmDataService.updateSendStatus((List<RecvCmData>) dataList, status);
			}
			msg = "更新数据状态成功";
			result.setSuccess(true);
			result.setMsg(msg);
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "更新数据状态失败:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}
	
	
	public Status feedbackSendStatusAndRoutelog(CmData cmData,String toCode,ExchageLifecycle exLifecycle) {
		initTransportPileline();
		logger.info(">>>>>>>>>>>>>>>>>feedbackSendStatusAndRoutelog:" + cmData);
		String msg = "";
		Status result = Status.getInstance();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			SendCmData sendCmData = new SendCmData();
			BeanMapper.copy(cmData, sendCmData);//TODO: 需要测试一下性能
			
			/*String pipeline = cmData.getPipeline();
			
			//将数据发送至对应的传输管道中
			if (AppConst.Pipeline.HTTP.value().equals(pipeline)) {
				httpTransportPipeline.sendSendStatusAndRouteLog(sendCmData);
			}
			if (AppConst.Pipeline.TLQ.value().equals(pipeline)) {
				transportPileline.sendSendStatusAndRouteLog(sendCmData);
			}*/
			
			transportPileline.sendLog(cmData, localNode.getNodeCode(), toCode, exLifecycle);
			msg = "路由日志发送成功";
			result.setSuccess(true);
			result.setMsg(msg);
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "更新数据状态失败:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	
	}
	
	
	public Status feedbackNotifyStatusAndRoutelog(SendCmData cmData,String toCode,ExchageLifecycle exLifecycle) {
		initTransportPileline();
		logger.info(">>>>>>>>>>>>>>>>>feedbackNotifyStatusAndRoutelog:" + cmData);
		String msg = "";
		Status result = Status.getInstance();
		NodeInfo localNode=null;
		try {
			localNode=baseInfoService.getCurrentNodeInfo();
			if(AppConst.YES.equals(cmData.getCrossNode())){
				/*String pipeline = cmData.getPipeline();
				//将数据发送至对应的传输管道中
				if (AppConst.Pipeline.HTTP.value().equals(pipeline)) {
					httpTransportPipeline.sendNofityStatusAndRoutLog(cmData);
				}
				if (AppConst.Pipeline.TLQ.value().equals(pipeline)) {
					transportPileline.sendNofityStatusAndRoutLog(cmData);
				}*/
				
				transportPileline.sendLog(cmData, localNode.getNodeCode(), toCode, exLifecycle);
				msg = "路由日志发送成功";
				result.setSuccess(true);
				result.setMsg(msg);
			}else{
				msg = "路由日志发送成功:节点内交换，不需要同步路由日志信息";
				result.setSuccess(true);
				result.setMsg(msg);
			}
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "更新数据状态失败:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}
	
	
	public Status updateSendStatusAndRoutelog(SendCmData cmData) {
		String msg = "";
		Status result = Status.getInstance();
		try {
			int i = sendCmDataService.updateIgnoreNull(cmData);
			if (i == 1) {
				msg = "路由日志信息更新成功";
				result.setSuccess(true);
				result.setMsg(msg);
			} else {
				msg = "路由日志信息更新失败";
				result.setSuccess(true);
				result.setMsg(msg);
			}
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "路由日志信息更新出现异常:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}
	
	public Status updateSendStatusAndRoutelog(CrossNetTmpCmData cmData) {
		String msg = "";
		Status result = Status.getInstance();
		try {
			int i = crossNetTmpCmDataService.updateIgnoreNull(cmData);
			if (i == 1) {
				msg = "路由日志信息更新成功";
				result.setSuccess(true);
				result.setMsg(msg);
			} else {
				msg = "路由日志信息更新失败";
				result.setSuccess(true);
				result.setMsg(msg);
			}
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "路由日志信息更新出现异常:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}
	
	public Status updateNotifyStatusAndRoutelog(CrossNetTmpCmData cmData) {
		String msg = "";
		Status result = Status.getInstance();
		try {
			int i = crossNetTmpCmDataService.updateIgnoreNull(cmData);
			if (i == 1) {
				msg = "路由日志信息更新成功";
				result.setSuccess(true);
				result.setMsg(msg);
			} else {
				msg = "路由日志信息更新失败";
				result.setSuccess(true);
				result.setMsg(msg);
			}
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "路由日志信息更新出现异常:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}
	
	
	public Status updateNotifyStatusAndRoutelog(SendCmData cmData) {
		String msg = "";
		Status result = Status.getInstance();
		try {
			if(AppConst.YES.equals(cmData.getCrossNode()) ){
				RecvCmData sendCmData = new RecvCmData();
				BeanMapper.copy(cmData, sendCmData);
				int i = recvCmDataService.updateIgnoreNull(sendCmData);
				if (i == 1) {
					msg = "路由日志信息更新成功";
					result.setSuccess(true);
					result.setMsg(msg);
				} else {
					msg = "路由日志信息更新失败";
					result.setSuccess(true);
					result.setMsg(msg);
				}
			}else{
				msg = "路由日志信息更新成功";
				result.setSuccess(true);
				result.setMsg(msg);
			}
			return result;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "路由日志信息更新出现异常:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
	}

	@Override
	public Status cleanUp() {
		/*String msg = "";
		Status result = Status.getInstance();
		try {
			WhereCondition parameter = new WhereCondition();
			parameter.where()
				.notEq("MSG_TYPE", Const.MsgType.GROUP_MSG.value())
				.and().eq("SEND_STATUS", Const.SendStatus.LOCAL_SENDING.value());
			List<SendCmData> deadMsgList = sendCmDataService.list(parameter);
			List<SendCmData> failMsgList = new ArrayList<SendCmData>();
			if (CollectionUtil.hasElement(deadMsgList)) {
				for (SendCmData cmdata : deadMsgList) {
					result = timeoutExpiredStrategy.isExpired(cmdata.getCreated());
					if (result.isSuccess()) {
						cmdata.setModified(new Date());
						cmdata.setSendStatus(Const.SendStatus.FAIL.value());
						failMsgList.add(cmdata);
					}
				}
			}
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "清理过期消息出现异常:" + e.fillInStackTrace();
			result.setSuccess(false);
			result.setMsg(msg);
			return result;
		}
		return result;*/
		return null;
	}

	/**
	 * 报文文件落地
	 * @param filePath
	 * @param data
	 * @return
	 */
	private Status storeFile(String filePath, String data) {
		String msg = "";
		Status status = Status.getInstance();
		try {
			File file = new File(AppConst.CMDATA_STORED_DIR +File.separator+ filePath);
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}
			FileUtils.writeStringToFile(file, data,ENCODING);
			msg = "数据体文件落地成功";
			status.setSuccess(true);
			status.setMsg(msg);
			return status;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "数据体文件落地出现异常:" + e.fillInStackTrace();
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
	}
	
	
	/**
	 * 将数据发送给业务系统
	 * @param cmData
	 * @return
	 */
	private Status sendDataToReciver(CmData cmData) {
		String msg = "";
		Status status = Status.getInstance();
		try {
			String filePath = AppConst.CMDATA_STORED_DIR + File.separator + cmData.getPayload();
			File file = new File(filePath);
			if (!file.exists()) {
				msg = "数据发送至业务系统失败：数据报文文件[" + filePath + "]找不到";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			String payload = FileUtils.readFileToString(file, AppConst.CHARSET_UTF8);
			Posthead posthead=XstreamUtil.toObject(Posthead.class, cmData.getPosthead());
			
			
			//先解密，然后解压缩
			//解密处理
			EncryptService encryptService = EncryptServiceFactory.createEncryptService(ENCRYPT_ALGORITHM.DES);
			//解压缩
			CompressService compressService = CompressServiceFactory.createCompressService(COMPRESS_ALGORITHM.JAVA_GZIP);
			
			
			List<ProcessInfo> list=posthead.getProcesses().getProcess();
			if (list!=null && !list.isEmpty()) {
				String compress=list.get(0).getCompress();
				String encrypt=list.get(0).getEncrypt();
				if (encrypt.equals("1")) {//解密
					String seed=encryptService.getSeed(posthead.getFrom().getNodecode()+posthead.getFrom().getAdaptorcode());
					payload=encryptService.decryptString(seed, payload);
				}
				if (compress.equals("1")) {//解压缩
					payload=compressService.uncompress(payload);
				}
			}
			
			//根据接收节点 接收适配器获取接收适配器信息
			AdapterInfo recvAdapterInfo = baseInfoService.getAdapterInfo(cmData.getRecvNodecode(), cmData.getRecvAdaptorcode());//baseInfoService.getSysServiceInfoBySysId(recvSys.getId());
			if(recvAdapterInfo == null){
				msg = "数据发送至业务系统失败:接收系统对应的适配器[" + cmData.getRecvAdaptorcode() + "]服务信息查找失败";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			String wsdl = recvAdapterInfo.getWsdlUrl();
			if(StrUtil.isBlank(wsdl)){
				msg = "数据发送至业务系统失败:接收系统对应的适配器[" + cmData.getRecvAdaptorcode() + "]接收服务地址未填写";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			/*DataExchRecvService dataExchRecvService = (DataExchRecvService) WebserviceUtil.getServicePort(wsdl,DataExchRecvService.class);*/
			HttpDataExchRecvService dataExchRecvService=new HttpDataExchRecvService(wsdl);
			String signed = null;
			Posthead formmatPosthead=this.formatt(posthead, cmData.getRecvNodecode(), cmData.getRecvAdaptorcode());
		    signed = dataExchRecvService.receive(XstreamUtil.toXml(formmatPosthead),cmData.getMetaData(), payload);
			
			msg = "数据发送至业务系统成功";
			status.setSuccess(true);
			status.setMsg(msg);
			status.setData(signed);
			return status;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "数据发送至业务系统出现异常:" + e.fillInStackTrace();
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
	}
	
	/**
	 * 将posthead格式化
	 * @param posthead
	 */
	private Posthead formatt(Posthead posthead,String nodecode,String adaptercode){
		Posthead newPosthead=posthead;
		List<RouteEntry> toList=posthead.getToList();
		List<RouteEntry> toNewList=new ArrayList<RouteEntry>();
		for (RouteEntry routeEntry : toList) {
			if (routeEntry.getNodecode().equals(nodecode)) {
				toNewList.add(routeEntry);
			}
		}
		newPosthead.setToList(toNewList);
		return newPosthead;
		
	}
	/**
	 * 将数据投递结果反馈给发送者
	 * @param cmData
	 * @return
	 */
	private Status sendResultToSender(CmData cmData) {
		String msg = "";
		Status status = Status.getInstance();
		try {
			//根据发送节点， 发送适配器编码获取发送适配器信息
			AdapterInfo sendAdapterInfo =baseInfoService.getAdapterInfo(cmData.getSendNodecode(), cmData.getSendAdaptorcode());// baseInfoService.getSysServiceInfoBySysId(sendSys.getId());
			if(sendAdapterInfo == null){
				msg = "数据投递结果反馈给发送系统失败:发送系统对应的适配器[" + cmData.getSendAdaptorcode() + "]服务信息查找失败";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			String wsdl = sendAdapterInfo.getWsdlUrl();
			if(StrUtil.isBlank(wsdl)){
				msg = "数据投递结果反馈给发送系统失败:发送系统对应的适配器[" + cmData.getSendAdaptorcode() + "]接收服务地址未填写";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			/*DataExchRecvService dataExchRecvService = (DataExchRecvService) WebserviceUtil.getServicePort(wsdl,DataExchRecvService.class);
			*/
			HttpDataExchRecvService dataExchRecvService=new HttpDataExchRecvService(wsdl);
			String signed = null;
			//发送状态
			signed = dataExchRecvService.receiveNotify(cmData.getPid(),cmData.getId(),
					AppConst.SendStatus.SENT.value().equals(cmData.getSendStatus())?"1":"0", cmData.getReciverSigned(),
							cmData.getMetaData());
			
			msg = "数据投递结果反馈给发送系统成功";
			status.setSuccess(true);
			status.setMsg(msg);
			status.setData(signed);
			return status;
		} catch (Exception e) {
			logger.error(msg, e);
			msg = "数据投递结果反馈给发送系统出现异常:" + e.fillInStackTrace();
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
	}
	
	
	/**
	 * 解析之前的初始化，初始化目录
	 */
	private void analyzeInit(File dir,File successDir,File errorDir){
		if (!dir.exists()) {
			dir.mkdirs();
		}
		if (!successDir.exists()) {
			   successDir.mkdirs();
		 }
	    if (!errorDir.exists()) {
		   errorDir.mkdirs();
	    }
	    
	    File splitDir=new File(AppConst.APP_CD_UPLOAD_SPLIT);
	    if (!splitDir.exists()) {
	    	splitDir.mkdirs();
		 }
	    File unionDir=new File(AppConst.APP_CD_UPLOAD_SPLIT);
	    if (!unionDir.exists()) {
	    	unionDir.mkdirs();
		}
	}
	
	/**
	 * 第一次解析，第一次解压缩
	 */
	private Status analyzeZip(File zipFile,File dir){
		Status status=Status.getInstance();
		try {
			Map<String,Object> map=new HashMap<String, Object>();
			CarvedDiscsUpload carvedDiscsUpload=carvedDiscsUploadService.getByUniqueProperty("carvedName", zipFile.getName());
			if (carvedDiscsUpload==null) {
				status.setMsg("第一次解压缩失败--非法文件");
				status.setSuccess(false);
			} else {
				map.put("vo", carvedDiscsUpload);
				try {
					ZipUtil.decompress(zipFile.getAbsolutePath(), dir.getAbsolutePath(), "gbk");
					File analyzeFile=new File(dir,zipFile.getName().substring(0,zipFile.getName().lastIndexOf(".")));//解压缩后的文件
					map.put("analyzeFile", analyzeFile);
					status.setMsg("第一次解压缩成功");
					status.setSuccess(true);
					status.setData(map);
				} catch (Exception e) {
					status.setMsg("第一次解压缩失败");
					status.setSuccess(false);
					status.setData(map);
				}
			}
			return status;
		} catch (ServiceException e) {
			logger.error(e);
		}
		status.setMsg("第一次解压缩时失败--查询失败");
		status.setSuccess(false);
		return status;
	}
	
	private boolean isContains(File[] files,String path){
		for (File f : files) {
			if (f.getAbsolutePath().equals(path)) {
				return true;
			}
		}
		return false;
	}
	/**
	 * 
	 * @param file
	 * @return 返回false表示不是一个拆包文件，返回true表示是一个拆包文件
	 */
	private Status unionFile(File file){
		Status status=Status.getInstance();
		try {
			List<String> list=fileSplit.getSplitFileListFromSplitFile(file.getAbsolutePath());
			//判断当前文件是否有所有的拆包文件，如果有则进行合并
			File[] files=file.getParentFile().listFiles();
			boolean flag=false;//用来标识当前目录是否有所有的拆包文件
			if (files.length<list.size()) {
				status.setMsg("是拆包后的一个子包，但是当前的子包还不能合并成一个包");
				status.setSuccess(flag);
				return status;
			}
			
			/**
			 * 判断files的路径是否包含list
			 */
			for (String string : list) {
				if (!isContains(files, string)) {
					status.setMsg("是拆包后的一个子包，但是当前的子包还不能合并成一个包");
					status.setSuccess(flag);
					return status;
				}
			}
			
			//合并包
			String	path=fileSplit.unionFile(true, list);
			status.setSuccess(true);
			status.setMsg("是拆包后的一个子包，所有的子包已经合并成一个包");
			status.setData(path);
			return status;
			
		} catch (FileSplitException e) {
			logger.error(e);
			status.setMsg("不是拆包后的一个子包，可以直接进行处理");
			status.setSuccess(false);
			return status;
		}
	}
	
	/**
	 * 处理第一次解压缩后的文件
	 * @param zipFileDir 第一次解压缩后的目录
	 * @return
	 */
	private Status processAnalyzeFile(File zipFileDir){
		Status status=Status.getInstance();
		//处理.zip文件 继续解压缩
		//第二次解压
		File[] zips=zipFileDir.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				if (pathname.getName().endsWith(".zip")) {
					return true;
				}
				return false;
			}
		});
		if (zips!=null && zips.length>0) {//第二次解压缩zip文件
			for (File file : zips) {
				try {
					ZipUtil.decompress(file.getAbsolutePath(), file.getParent(), "gbk");
					File zipFile=new File(file.getParent(),file.getName().substring(0,file.getName().lastIndexOf(".")));
					String orderIds=analyzeOrder(zipFile);//解析数据，返回订单id
					status.setMsg("解析入库成功");
					status.setSuccess(true);
					status.setData(orderIds);
				} catch (Exception e) {
					status.setMsg("第二次解压缩失败");
					status.setSuccess(false);
					return status;
				}
			}
		}
		
		
		//处理.split文件 ,直接拷贝到AppConst.APP_CD_UPLOAD目录
		File[] splitFiles=zipFileDir.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				if (pathname.getName().endsWith(FileSplitStatic.SPLIT_FILE_SUFFIX)) {
					return true;
				}
				return false;
			}
		});
		if(splitFiles!=null && splitFiles.length>0){
			for (File file : splitFiles) {
				try {
					File newFile=new File(AppConst.APP_CD_UPLOAD_SPLIT,file.getName());
					FileUtils.copyFile(file, newFile);
					//进行子包检查，判断是否子包全部到齐
					Status sta=this.unionFile(newFile);//进行合包
					if (sta.isSuccess()) {//如果为true表示是拆包后的一个子包
						if (sta.getData()!=null && !"".equals(sta.getData().toString())) {
							File zip=new File(sta.getData().toString());
							//解压缩包
							ZipUtil.decompress(zip.getAbsolutePath(), zip.getParent(), "gbk");
							//解压后的目录
							File zipDir=new File(zip.getAbsolutePath().substring(0,zip.getAbsolutePath().lastIndexOf(".")));
							
							//解析入库
							try {
								String orderIds=this.analyzeOrder(zipDir);
								status.setSuccess(true);
								status.setMsg("包合并解析成功");
								if (status.getData()!=null) {
									status.setData(status.getData().toString()+","+orderIds);
								}else {
									status.setData(orderIds);
								}
								
								//删除合并包zip及解压后的目录
								if(TurboUtil.deleteFile(zip)){
									   logger.info("文件"+zip.getAbsolutePath()+"删除成功!");
								  }else{
									   logger.info("文件"+zip.getAbsolutePath()+"删除失败!");
								   }
								if(TurboUtil.deleteFile(zipDir)){
									   logger.info("文件"+zipDir.getAbsolutePath()+"删除成功!");
								   }else{
									   logger.info("文件"+zipDir.getAbsolutePath()+"删除失败!");
								   }
							} catch (Exception e) {
								logger.error(e);
							}
						}else{
							continue;
						}
						
					}
					
				} catch (IOException e) {
					status.setMsg("将子包文件拷贝到上传目录失败");
					status.setSuccess(false);
					return status;
				} 
			}
		}
		status.setSuccess(true);
		status.setMsg("解析成功");
		return status;
	}

	/**
	 * 解析处理上传的zip文件
	 */
	@SuppressWarnings("unchecked")
	public  Status processUploadFile() {
		Status status=Status.getInstance();
		        List<File> deleteFiles=new ArrayList<File>();//要删除的文件列表
		        File dir=new File(AppConst.APP_CD_UPLOAD);//文件上传的目录
		        File  successDir=new File(new File(AppConst.APP_CD_UPLOAD).getParent(),"bak"); //解析成功移到BAK文件夹备份
		        File  errorDir=new File(new File(AppConst.APP_CD_UPLOAD).getParent(),"error"); //解析成功移到BAK文件夹备份
				this.analyzeInit(dir,successDir,errorDir);//初始化解析目录
				//第一次解析，解析.zip文件
				//需要解析的zip文件
				File[] files=dir.listFiles(new FileFilter() {
					@Override
					public boolean accept(File pathname) {
						String filename=pathname.getName();
						if (filename.contains("sl_exch_") && filename.lastIndexOf(".zip")>-1) {
							return true;
						}
						return false;
					}
				});
				
				if (files!=null && files.length>0) {//第一次解压缩zip文件
					for (File file : files) {
						status=this.analyzeZip(file, dir);//解压缩
						if (status.isSuccess()) {//如果解析成功,继续解析
							Map<String,Object> map=(Map<String, Object>) status.getData();
							CarvedDiscsUpload carvedDiscsUpload=(CarvedDiscsUpload) map.get("vo");
							File analyzeFile=(File) map.get("analyzeFile");
							deleteFiles.add(file);
							deleteFiles.add(analyzeFile);
							//二次解析处理
							status=this.processAnalyzeFile(analyzeFile);
							if (status.isSuccess()) {
								String orderId=(String) status.getData();
								 carvedDiscsUpload.setAnalyzeStatus(AppConst.AnalyzeStatus.ANALYZE_SUCCESS.value());
								 carvedDiscsUpload.setAnalyzeMsg("解析成功！");
								 carvedDiscsUpload.setOrderId(orderId);
								 try {
									FileUtils.copyFileToDirectory(file, successDir);
								} catch (IOException e) {
									logger.error(e);
								}
								 
							}else{
								carvedDiscsUpload.setAnalyzeStatus(AppConst.AnalyzeStatus.ANALYZE_FAIL.value());
								carvedDiscsUpload.setAnalyzeMsg("解析失败:文件损坏，请重新上传");
								try {
									FileUtils.copyFileToDirectory(file, errorDir);
								} catch (IOException e) {
									logger.error(e);
								}
							}
							try {
								carvedDiscsUploadService.update(carvedDiscsUpload);
							} catch (ServiceException e) {
								logger.error(e);
							}
						}else{
							if (status.getData() instanceof Map) {//解析失败
								Map<String,Object> map=(Map<String, Object>) status.getData();
								CarvedDiscsUpload carvedDiscsUpload=(CarvedDiscsUpload) map.get("vo");
								carvedDiscsUpload.setAnalyzeStatus(AppConst.AnalyzeStatus.ANALYZE_FAIL.value());
								carvedDiscsUpload.setAnalyzeMsg("解析失败:文件损坏，请重新上传");
								try {
									carvedDiscsUploadService.update(carvedDiscsUpload);
								} catch (ServiceException e) {
									logger.error(e);
								}
							}
							//文件移入error文件夹
							try {
								FileUtils.copyFileToDirectory(file, errorDir);
							} catch (IOException e) {
								logger.error(e);
							}
							
						}
						
						
					}
					
				}
		//文件的删除
	   if (!deleteFiles.isEmpty()) {
		   for (File file : deleteFiles) {
			   if(TurboUtil.deleteFile(file)){
				   logger.info("文件"+file.getAbsolutePath()+"删除成功!");
			   }else{
				   logger.info("文件"+file.getAbsolutePath()+"删除失败!");
			   }
			   
		   }
	   }
		
		return null;
	}
	/**
	 * 解析解压后的文件
	 * @param analyzeFile
	 * @throws Exception 
	 */
	@SuppressWarnings({ "unchecked" })
	public String analyzeOrder(File analyzeFile) throws Exception{
//		Status status=Status.getInstance();
		StringBuffer orderIds=new StringBuffer();
		File[] orders=analyzeFile.listFiles();
		 NodeInfo localNode=baseInfoService.getCurrentNodeInfo();
		if (orders!=null && orders.length>0) {
			for (File order : orders) {
				//得到json文件
				File[] jsonFile=order.listFiles(new FileFilter() {
					@Override
					public boolean accept(File pathname) {
						if (pathname.getName().lastIndexOf(".json")>-1) {
							return true;
						}
						return false;
					}
				});
				if (jsonFile==null || jsonFile.length!=1) {
					return null;
				}
			   Map<String,String> map=(Map<String, String>) JsonUtil.toMap(jsonFile[0]);
			   CarvedDiscsUploadData carvedDiscsUploadData=JsonUtil.toObject(JsonUtil.toJson(map.get("carvedDiscsData")), CarvedDiscsUploadData.class);
			   
			  // 非json文件,即数据文件
			   File[] fs=order.listFiles(new FileFilter() {
					@Override
					public boolean accept(File pathname) {
						if (pathname.getName().lastIndexOf(".json")==-1) {
							return true;
						}
						return false;
					}
				});
			   //
			   carvedDiscsUploadDataService.insertOrUpdate(carvedDiscsUploadData);
			   if (carvedDiscsUploadData.getDataType().equals(AppConst.ExchDataType.CM_DATA.value())) {
				//数据文件移入到AppConst.CMDATA_STORED_DIR
				   //this.copy(fs, new File(AppConst.CMDATA_STORED_DIR));
				   List<SendCmData>  list=JsonUtil.toObjectList(JsonUtil.toJson(map.get("data")), SendCmData.class);
				   this.insertBatchAndStore(list,fs[0]);
			   }else{
				   //TODO 非结构化数据文件
				   //非结构化数据文件存储位置
				   String globalUploadmetadataDir=AppConst.FILEDATA_GLOBALUPLOADMETADATA_DIR;
				   File globaluploalpath = new File(globalUploadmetadataDir, AppConst.dFormat.format(new Date()));
				   List<SendFileData>  list=JsonUtil.toObjectList(JsonUtil.toJson(map.get("data")), SendFileData.class);
				   if (list!=null && !list.isEmpty()) {
					   for (SendFileData sendFileData : list) {
							
							sendFileData.setModified(new Date());
						
							if (NodeInfoParam.isInnerNode()) {
								sendFileData.setInnerGapNodeCode(localNode.getNodeCode());
							}else{
								sendFileData.setOutGapNodeCode(localNode.getNodeCode());
							}
							try {
								for (File f : fs) {//将数据文件转储
									FileUtils.copyFileToDirectory(f, globaluploalpath);//
								}
								 sendFileData.setFilehome(globaluploalpath.getAbsolutePath());//home目录
								sendFileData.setSendStatus( AppConst.SendStatus.ANALYZE_SUCESS.value());
								RouteLog.setAnalyzeStore(sendFileData, AppConst.YES, "数据解析入库成功", AppConst.dtFormat.format(new Date()));
							} catch (Exception e) {
								sendFileData.setSendStatus( AppConst.SendStatus.ANALYZE_FAIL.value());
								RouteLog.setAnalyzeStore(sendFileData, AppConst.NO, "数据解析入库失败", AppConst.dtFormat.format(new Date()));
							}
							sendFileDataService.insertOrUpdate(sendFileData);
					   }
				  } 
				   
			   }
			   orderIds.append(carvedDiscsUploadData.getId()+",");
			}
			
			return orderIds.delete(orderIds.length()-1, orderIds.length()).toString();
		}
		return null;
	}
	
	
	
	
	private void insertBatchAndStore(List<SendCmData> list,File dataFile) throws ServiceException{
//		Status status=Status.getInstance();
		String msg=null;
		if (list!=null && !list.isEmpty()) {
			try {
				NodeInfo localNode=baseInfoService.getCurrentNodeInfo();
				for (SendCmData sendCmData : list) {
					FileUtils.copyFile(dataFile, new File(AppConst.CMDATA_STORED_DIR,sendCmData.getPayload()));//数据文件的拷贝
				   if (NodeInfoParam.isInnerNode()) {
					   sendCmData.setInnerGapNodeCode(localNode.getNodeCode());
					}else{
						sendCmData.setOutGapNodeCode(localNode.getNodeCode());
					}
					sendCmData.setModified(new Date());
					sendCmData.setSendStatus(AppConst.SendStatus.ANALYZE_SUCESS.value());
					msg="数据解析入库成功";
					RouteLog.setAnalyzeStore(sendCmData, AppConst.YES, msg, AppConst.dtFormat.format(new Date()));
					sendCmDataService.insertOrUpdate(sendCmData);
				}
			} catch (Exception e) {
				logger.error(e);
			}
		}
	}
	
	@SuppressWarnings("unused")
	private void copy(File[] files,File destDir) throws IOException{
		if (files!=null && files.length>0) {
			for (File file : files) {
					FileUtils.copyFileToDirectory(file, destDir);
			}
		}
	}
	
//	public static void main(String[] args) throws FileNotFoundException, IOException {
//		ZipUtil.compress("F:\\sql\\upload\\bak\\sl_exch_000000201_201411325150131", "F:\\sql\\upload\\bak", "gbk", "");
//	}

}
